from flask import Blueprint, request, jsonify
from flask_jwt_extended import jwt_required
from app import db
from app.models import Role, Permission, Menu
from app.utils.decorators import admin_required

roles_bp = Blueprint('roles', __name__)

@roles_bp.route('/', methods=['GET'])
@jwt_required()
@admin_required
def get_roles():
    """获取角色列表"""
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    search = request.args.get('search', '')
    
    query = Role.query
    
    if search:
        query = query.filter(
            db.or_(
                Role.name.contains(search),
                Role.code.contains(search),
                Role.description.contains(search)
            )
        )
    
    pagination = query.paginate(
        page=page, per_page=per_page, error_out=False
    )
    
    roles = pagination.items
    
    return jsonify({
        'roles': [role.to_dict() for role in roles],
        'pagination': {
            'page': page,
            'per_page': per_page,
            'total': pagination.total,
            'pages': pagination.pages
        }
    }), 200

@roles_bp.route('/<int:role_id>', methods=['GET'])
@jwt_required()
@admin_required
def get_role(role_id):
    """获取角色详情"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    return jsonify({'role': role.to_dict()}), 200

@roles_bp.route('/', methods=['POST'])
@jwt_required()
@admin_required
def create_role():
    """创建角色"""
    data = request.get_json()
    
    if not data:
        return jsonify({'message': '请求数据不能为空'}), 400
    
    name = data.get('name')
    code = data.get('code')
    description = data.get('description', '')
    
    if not name or not code:
        return jsonify({'message': '角色名称和编码不能为空'}), 400
    
    # 检查角色名称是否已存在
    if Role.query.filter_by(name=name).first():
        return jsonify({'message': '角色名称已存在'}), 400
    
    # 检查角色编码是否已存在
    if Role.query.filter_by(code=code).first():
        return jsonify({'message': '角色编码已存在'}), 400
    
    role = Role(
        name=name,
        code=code,
        description=description
    )
    
    # 分配权限
    permission_ids = data.get('permission_ids', [])
    if permission_ids:
        permissions = Permission.query.filter(Permission.id.in_(permission_ids)).all()
        role.permissions = permissions
    
    # 分配菜单
    menu_ids = data.get('menu_ids', [])
    if menu_ids:
        menus = Menu.query.filter(Menu.id.in_(menu_ids)).all()
        role.menus = menus
    
    try:
        db.session.add(role)
        db.session.commit()
        return jsonify({
            'message': '角色创建成功',
            'role': role.to_dict()
        }), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'message': '角色创建失败'}), 500

@roles_bp.route('/<int:role_id>', methods=['PUT'])
@jwt_required()
@admin_required
def update_role(role_id):
    """更新角色"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    data = request.get_json()
    
    if not data:
        return jsonify({'message': '请求数据不能为空'}), 400
    
    # 允许更新的字段
    allowed_fields = ['name', 'code', 'description', 'is_active']
    
    for field in allowed_fields:
        if field in data:
            setattr(role, field, data[field])
    
    # 更新权限
    if 'permission_ids' in data:
        permission_ids = data['permission_ids']
        permissions = Permission.query.filter(Permission.id.in_(permission_ids)).all()
        role.permissions = permissions
    
    # 更新菜单
    if 'menu_ids' in data:
        menu_ids = data['menu_ids']
        menus = Menu.query.filter(Menu.id.in_(menu_ids)).all()
        role.menus = menus
    
    try:
        db.session.commit()
        return jsonify({
            'message': '角色更新成功',
            'role': role.to_dict()
        }), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'message': '角色更新失败'}), 500

@roles_bp.route('/<int:role_id>', methods=['DELETE'])
@jwt_required()
@admin_required
def delete_role(role_id):
    """删除角色"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    try:
        db.session.delete(role)
        db.session.commit()
        return jsonify({'message': '角色删除成功'}), 200
    except Exception as e:
        db.session.rollback()
        return jsonify({'message': '角色删除失败'}), 500

@roles_bp.route('/<int:role_id>/permissions', methods=['POST'])
@jwt_required()
@admin_required
def assign_permissions(role_id):
    """分配权限给角色"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    data = request.get_json()
    
    if not data:
        return jsonify({'message': '请求数据不能为空'}), 400
    
    permission_ids = data.get('permission_ids', [])
    
    if not permission_ids:
        return jsonify({'message': '权限ID列表不能为空'}), 400
    
    try:
        # 查找权限
        permissions = Permission.query.filter(Permission.id.in_(permission_ids)).all()
        
        if len(permissions) != len(permission_ids):
            return jsonify({'message': '部分权限不存在'}), 400
        
        # 分配权限
        role.permissions = permissions
        db.session.commit()
        
        return jsonify({
            'message': '权限分配成功',
            'role': role.to_dict()
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'message': '权限分配失败'}), 500

@roles_bp.route('/<int:role_id>/menus', methods=['POST'])
@jwt_required()
@admin_required
def assign_menus(role_id):
    """分配菜单给角色"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    data = request.get_json()
    
    if not data:
        return jsonify({'message': '请求数据不能为空'}), 400
    
    menu_ids = data.get('menu_ids', [])
    
    if not menu_ids:
        return jsonify({'message': '菜单ID列表不能为空'}), 400
    
    try:
        # 查找菜单
        menus = Menu.query.filter(Menu.id.in_(menu_ids)).all()
        
        if len(menus) != len(menu_ids):
            return jsonify({'message': '部分菜单不存在'}), 400
        
        # 分配菜单
        role.menus = menus
        db.session.commit()
        
        return jsonify({
            'message': '菜单分配成功',
            'role': role.to_dict()
        }), 200
        
    except Exception as e:
        db.session.rollback()
        return jsonify({'message': '菜单分配失败'}), 500

@roles_bp.route('/<int:role_id>/permissions', methods=['GET'])
@jwt_required()
@admin_required
def get_role_permissions(role_id):
    """获取角色的权限列表"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    permissions = role.permissions
    return jsonify({
        'permissions': [perm.to_dict() for perm in permissions]
    }), 200

@roles_bp.route('/<int:role_id>/menus', methods=['GET'])
@jwt_required()
@admin_required
def get_role_menus(role_id):
    """获取角色的菜单列表"""
    role = Role.query.get(role_id)
    
    if not role:
        return jsonify({'message': '角色不存在'}), 404
    
    menus = role.menus
    return jsonify({
        'menus': [menu.to_dict() for menu in menus]
    }), 200 